﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Collections;
using System.Xml;
//using SerialRequest;
namespace SerialPorts
{
    public partial class Form1 : Form
    {
        private SerialPort comm = new SerialPort();  
        private bool IsStart = false;
        private bool IsComplete = false;
        private long send_count = 0;
        SerialRequest lds = new SerialRequest();
        private byte[] reactFrame = { 0x01, 0x02, 0x00};
        private ArrayList receivedFrame = new ArrayList();
        public enum COMMAND_TYPE
        {
            SWITCH,
            BRIGHTNESS,
            REBOOT
        }
        private int intType;
        public Form1()
        {
            InitializeComponent();       
        }
        
        private void Form1_Load(object sender, EventArgs e)
        {
            string[] str = SerialPort.GetPortNames();
            if (str == null)
            {
                MessageBox.Show("本机没有串口!", "Error");
                return;
            }
            Array.Sort(str);
            cbSerial.Items.AddRange(str);  
            cbSerial.SelectedIndex = 0;
            
            //comm.NewLine = "/r/n";
            comm.RtsEnable = true;
            comm.DataReceived += comm_DataReceived;
        }

        private void comm_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            timerout.Enabled = false;
            System.Threading.Thread.Sleep(200);
            int n = comm.BytesToRead;
/*
            if (n < 4)
            {
                return;
            }*/
            try
            {
                if (IsComplete)
                {
                    IsComplete = false;
                    char[] buf = new char[n];
                    comm.Read(buf, 0, n);
                    if(buf[0]!=0x01)
                    {
                        return;
                    }
                    string strbuf = new string(buf);
                    strbuf = strbuf.Substring(2, n - 4);
                    bool uSucces = ParseReplyPackage(strbuf);
                    if (uSucces)
                    {
                        MessageBox.Show(Error);
                    }
                    else
                    {
                        MessageBox.Show("通信失败");
                    }
                }
                else
                {
                    byte[] buf = new byte[n];
                    // received_count += n;
                    comm.Read(buf, 0, n);
                    if (buf[0] != 0x01)
                    {
                        return;
                    }
                   
                    if (IsStart)
                    {
                        if (byteEquals(buf, reactFrame, reactFrame.Length))
                        {
                            if (buf[reactFrame.Length] == 0x00)
                            {
                                IsStart = false;
                                IsComplete = true;
                            }
                            else if (buf[reactFrame.Length] == 0x01)
                            {
                                send_Date(intType);
                            }
                        }
                    }
                }
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
        private bool byteEquals(byte[] buf1, byte[] buf2, int length)
        {
            for (int i = 0; i < length; i++)
            {
                if (buf1[i] != buf2[i])
                {
                    return false;
                }
            }
            return true;
        }
        private void send_Date(int type)
        {
            switch ((COMMAND_TYPE)type)
            {
                case COMMAND_TYPE.SWITCH:
                    GetSwitchPackSend();
                    break;
                case COMMAND_TYPE.BRIGHTNESS:
                    GetBrightPackSend();
                    break;
                case COMMAND_TYPE.REBOOT:
                    GetRebootPackSend();
                    break;
            }
        }
        private void btnOpenClose_Click(object sender, EventArgs e)
        {
            if (comm.IsOpen)
            {
                btnOpenClose.Text = "打开串口";
                cbSerial.Enabled = true;
                comm.Close();
            }
            else
            {
                btnOpenClose.Text = "关闭串口";
                comm.PortName = cbSerial.Text;
                cbSerial.Enabled = false;
                comm.BaudRate = 9600;
                comm.DataBits = 8;
                comm.StopBits = System.IO.Ports.StopBits.One;
                comm.Parity = System.IO.Ports.Parity.None;
                try
                {
                    comm.Open();
                }
                catch (System.Exception ex)
                {
                    comm = new SerialPort();
                    MessageBox.Show(ex.Message);
                }
            }
        }
   
        public void GetSwitchPackSend()
        {
            SerialSwitchRequest request = new SerialSwitchRequest(valNode);
            if (!request.CreatPackage())
            {

                return;
            }
            //string responseData = PostXml(url, request.URL);           
            string responseData = request.SendStr;
            ID = request.ID;
            TypeRequest = request.TypeRequest;
            SendPack(responseData);
            
        }
        public void GetBrightPackSend()
        {
            SerialBrightRequest request = new SerialBrightRequest(valNode);
            if (!request.CreatPackage())
            {

                return;
            }
            //string responseData = PostXml(url, request.URL);           
            string responseData = request.SendStr;
            ID = request.ID;
            TypeRequest = request.TypeRequest;
            SendPack(responseData);
        }
        public void GetRebootPackSend()
        {
            SerialRebootRequest request = new SerialRebootRequest();
            if (!request.CreatPackage())
            {

                return;
            }
            //string responseData = PostXml(url, request.URL);           
            string responseData = request.SendStr;
            ID = request.ID;
            TypeRequest = request.TypeRequest;
            SendPack(responseData);
        }
        private void SendPack(string responseData)
        {
            byte[] returnBytes = new byte[responseData.Length + 6];
            ushort checkSum = 0;
            returnBytes[0] = 0x01;
            returnBytes[1] = 0x02;
            for (int i = 2; i < responseData.Length + 2; i++)
            {
                returnBytes[i] = (byte)responseData[i - 2];
                checkSum += returnBytes[i];
            }
            returnBytes[2 + responseData.Length] = 0x03;
            returnBytes[3 + responseData.Length] = 0x04;
            returnBytes[4 + responseData.Length] = (byte)(checkSum / 256);
            returnBytes[5 + responseData.Length] = (byte)(checkSum % 256);
            if (!comm.IsOpen)
            {

                MessageBox.Show("串口没有打开，请打开串口！");

                return;

            }
            comm.Write(returnBytes, 0, returnBytes.Length);
            timerout.Enabled = true;
        }
        public XmlNode rootNode;
        public string ID;
        public string TypeRequest;     
        public string Error;
        public bool ParseReplyPackage(string replayDate)
        {
            if (string.IsNullOrEmpty(replayDate))
                return false;
            try
            {
                XmlDocument redoc = new XmlDocument();
                redoc.LoadXml(replayDate);

                rootNode = redoc.SelectSingleNode("/package/task");
                if (rootNode == null)
                    return false;
                string id = rootNode.Attributes["id"].Value;
                string type = rootNode.Attributes["type"].Value;
                string result = rootNode.Attributes["status"].Value;
                Error = rootNode.Attributes["error"].Value;
                if (TypeRequest == "REBOOT")
                {
                    Error = "SUCCESS";
                    return true;
                }
                if (id != ID || type != TypeRequest || result != "SUCCESS")
                    return false;


            }
            catch (System.Exception ex)
            {
                if (TypeRequest == "REBOOT")
                {
                    Error = "SUCCESS";
                    return true;
                }
                return false;
            }
            return true;
        }
        string valNode;
        private void btnSwitch1_Click(object sender, EventArgs e)
        {
            valNode = "1";
            intType = 0;
            send_Date(intType);
            IsStart = true;
        }

        private void btnSwitch0_Click(object sender, EventArgs e)
        {
            valNode = "0";
            intType = 0;
            send_Date(intType);
            IsStart = true;
        }
        private void btnBright_Click(object sender, EventArgs e)
        {
            valNode = tbrBright.Value.ToString();
            intType = 1;
            send_Date(intType);
            IsStart = true;
        }

        private void btnReBoot_Click(object sender, EventArgs e)
        {
            intType = 2;
            send_Date(intType);
            IsStart = true;
        }
        private void timerout_Tick(object sender, EventArgs e)
        {
            timerout.Enabled = false;
            MessageBox.Show("接收超时，请检查串口");
        }
    }
}

/*
<package version="1.0">
  <task id="0"type="SWITCH"status="SUCCESS"error="SUCCESS"/>
</package>*/